import UIKit
import Foundation

extension Array {
    
    func get(index: Int) -> Element? {
        if 0 <= index && index < count {
            return self[index]
        } else {
            return nil
        }
    }
    
    mutating func moveItem(fromIndex oldIndex: Index, toIndex newIndex: Index) {
        insert(removeAtIndex(oldIndex), atIndex: newIndex)
    }
}

// Groupon Interview Q2

/*

1 1 1    0,0 0,1 0,2
0 0 0    1,0 1,1 1,2
1 1 1    2,0 2,1 2,2

0 1 0
0 0 0
0 1 0


1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.
2. Any live cell with two or three live neighbours lives on to the next generation.
3. Any live cell with more than three live neighbours dies, as if by over-population.
4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

*/

var gameGrid = [[1,1,1], [0,0,0], [1,1,1]]

func game (array: [[Int]]) -> [[Int]] {
    
    let arrayRowsIndex = array.count - 1
    let arrayColumnIndex = array[0].count - 1
    var output = array
    
    var liveNeighbours: Int = 0
    var deadNeighbours: Int = 0
    
    for (rowIndex, rowElement) in output.enumerate() {
        
        for (colIndex, colElement) in rowElement.enumerate() {
            
            print(rowIndex, colIndex)
            print(array[rowIndex][colIndex])
            
            // above of element
            if (colIndex - 1) >= 0 {
                
                switch array[rowIndex][colIndex - 1] {
                case 1:
                    liveNeighbours += 1
                default:
                    deadNeighbours += 1
                }
            }
            
            // below of element
            if (colIndex + 1) <= arrayColumnIndex {
                
                switch array[rowIndex][colIndex + 1] {
                case 1:
                    liveNeighbours += 1
                default:
                    deadNeighbours += 1
                }
            }
            
            // left of element
            if (rowIndex - 1) >= 0 {
                
                switch array[rowIndex - 1][colIndex] {
                case 1:
                    liveNeighbours += 1
                default:
                    deadNeighbours += 1
                }
            }
            
            // right of element
            if (rowIndex + 1) <= arrayRowsIndex {
                
                switch array[rowIndex + 1][colIndex] {
                case 1:
                    liveNeighbours += 1
                default:
                    deadNeighbours += 1
                }
            }
            
            // below + right of element
            if (rowIndex + 1) <= arrayRowsIndex && (colIndex + 1) <= arrayColumnIndex {
                
                switch array[rowIndex + 1][colIndex + 1] {
                case 1:
                    liveNeighbours += 1
                default:
                    deadNeighbours += 1
                }
            }
            
            // above + left of element
            if (rowIndex - 1) >= 0 && (colIndex - 1) >= 0 {
                
                switch array[rowIndex - 1][colIndex - 1] {
                case 1:
                    liveNeighbours += 1
                default:
                    deadNeighbours += 1
                }
            }
            
            // below + left of element 
            if (rowIndex + 1) <= arrayRowsIndex && (colIndex - 1) >= 0 {
                
                switch array[rowIndex + 1][colIndex - 1] {
                case 1:
                    liveNeighbours += 1
                default:
                    deadNeighbours += 1
                }
            }
            
            // above + right of element
            if (rowIndex - 1) >= 0 && (colIndex + 1) <= arrayColumnIndex {
                
                switch array[rowIndex - 1][colIndex + 1] {
                case 1:
                    liveNeighbours += 1
                default:
                    deadNeighbours += 1
                }
            }
        
            print("liveNeighbours", liveNeighbours)
            print("deadNeighbours", deadNeighbours)
            
            switch (liveNeighbours, deadNeighbours) {
                
            case (let liveNeighbours, let deadNeighbours) where liveNeighbours < 2:
                // fewer than 2 live neighbours dies
                output[rowIndex][colIndex] = 0
                
            case (let liveNeighbours, let deadNeighbours) where liveNeighbours >= 2:
                
                // 2 or more neighbours lives on
                break
            
            case (let liveNeighbours, let deadNeighbours) where liveNeighbours > 3:
                
                // with more than 3 live neighbours dies
                output[rowIndex][colIndex] = 0
                
            case (let liveNeighbours, let deadNeighbours) where liveNeighbours == 3:
                
                // exactly 3 live neighbours comes back to life
                output[rowIndex][colIndex] = 1
                
            default:
                break
            }
            
            liveNeighbours = 0
            deadNeighbours = 0
        }
    }
    
    return output
}

print(game(gameGrid))

/*
Output = [[0, 1, 0], [0, 0, 0], [0, 1, 0]]
*/